////
////  AirObjectRefPoint.h
////  AirMem
////
////  Created by Penghao on 14-1-23.
////  Copyright (c) 2014年 PengHao.
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
////
//
//#ifndef __AirMem__AirObjectRefPoint__
//#define __AirMem__AirObjectRefPoint__
//
//#include <iostream>
//#include "AirObject.h"
//
//namespace AirCpp {
//    
//    template <class T>
//    class AirObjectAssign;
//    
//    template <class T>
//    class AirObjectRetain;
//    
//    template <class T>
//    class AirObjectCopy;
//    
//    template <template <class> class Protocol, class T>
//    class AirObjectPtr;
//    
//    template <class T>
//    class AirObjectBasePtr{
//    public:
//        T *p_t;
//    };
//    
//    
//    template <class T>
//    class AirObjectAssign : public AirObjectBasePtr<T>{
//    public:
//        
//        AirObjectAssign(){ AirObjectBasePtr<T>::p_t = NULL;}
//        
//        AirObjectAssign(T *t){ AirObjectBasePtr<T>::p_t = t; }
//        
//        AirObjectAssign(AirObjectPtr<AirObjectCopy, T> &foo){ AirObjectBasePtr<T>::p_t = foo.p_t; }
//        AirObjectAssign(AirObjectPtr<AirObjectRetain, T> &foo){ AirObjectBasePtr<T>::p_t = foo.p_t; }
//        
//        ~AirObjectAssign(){ AirObjectBasePtr<T>::p_t = NULL; }
//        
//        T& operator *(){
//            return *AirObjectBasePtr<T>::p_t;
//        }
//        
//        T* operator ->(void){
//            return AirObjectBasePtr<T>::p_t;
//        }
//        
//        
//        bool operator ==(T& t){
//            return AirObjectBasePtr<T>::p_t == &t;
//        }
//        
//        bool operator ==(AirObjectAssign &obj){
//            return AirObjectBasePtr<T>::p_t == obj.p_t;
//        }
//        
//        AirObjectAssign *operator=(T *_t)
//        {
//            AirObjectBasePtr<T>::p_t = _t;
//            return this;
//        }
//        
//        AirObjectAssign &operator=(T &_t)
//        {
//            AirObjectBasePtr<T>::p_t = &_t;
//            return *this;
//        }
//        
//        AirObjectAssign &operator=(AirObjectAssign &foo)
//        {
//            AirObjectBasePtr<T>::p_t = &(*(&foo)->p_t);
//            return *this;
//        }
//        
//        AirObjectAssign &operator=(const AirObjectAssign &foo)
//        {
//            AirObjectBasePtr<T>::p_t = &(*(&foo)->p_t);
//            return *this;
//        }
//        
//        AirObjectAssign &operator=(AirObjectPtr<AirObjectRetain, T> &foo)
//        {
//            AirObjectBasePtr<T>::p_t = &(*(&foo)->p_t);
//            return *this;
//        }
//        
//        AirObjectAssign &operator=(const AirObjectPtr<AirObjectRetain, T> &foo)
//        {
//            AirObjectBasePtr<T>::p_t = &(*(foo.p_t));
//            return *this;
//        }
//        
//        AirObjectAssign &operator=(AirObjectPtr<AirObjectCopy, T> &foo)
//        {
//            AirObjectBasePtr<T>::p_t = &(*(&foo)->p_t);
//            return *this;
//        }
//        
//        AirObjectAssign &operator=(const AirObjectPtr<AirObjectCopy, T> &foo)
//        {
//            AirObjectBasePtr<T>::p_t = &(*(foo.p_t));
//            return *this;
//        }
//    };
//    
//    template <class T>
//    class AirObjectRetain : public AirObjectBasePtr<T>{
//    public:
//        AirObjectRetain(){ AirObjectBasePtr<T>::p_t = NULL;}
//        
//        AirObjectRetain(T *t){
//            if (NULL != t) {
//                t->retain();
//            }
//            AirObjectBasePtr<T>::p_t = t;
//        }
//        
//        AirObjectRetain(AirObjectPtr<AirObjectCopy, T> &foo){ AirObjectBasePtr<T>::p_t = foo.p_t; }
//        AirObjectRetain(AirObjectPtr<AirObjectAssign, T> &foo){ AirObjectBasePtr<T>::p_t = foo.p_t; }
//        ~AirObjectRetain(){
//            if (AirObjectBasePtr<T>::p_t!=NULL) {
//                AirObjectBasePtr<T>::p_t->release();
//            }
//            AirObjectBasePtr<T>::p_t = NULL;
//        }
//        
//        T& operator *(){
//            return *AirObjectBasePtr<T>::p_t;
//        }
//        
//        T* operator ->(void){
//            return AirObjectBasePtr<T>::p_t;
//        }
//        
//        bool operator ==(T& t){
//            return AirObjectBasePtr<T>::p_t == &t;
//        }
//        
//        
//        AirObjectRetain *operator=(T *_t)
//        {
//            if (NULL != _t) {
//                _t->retain();
//            }
//            if (NULL != AirObjectBasePtr<T>::p_t) {
//                AirObjectBasePtr<T>::p_t->release();
//            }
//            AirObjectBasePtr<T>::p_t = _t;
//            return this;
//        }
//        
//        AirObjectRetain &operator=(T &_t)
//        {
//            _t.retain();
//            if (NULL != AirObjectBasePtr<T>::p_t) {
//                AirObjectBasePtr<T>::p_t->release();
//            }
//            AirObjectBasePtr<T>::p_t = &_t;
//            return *this;
//        }
//        
//        AirObjectRetain &operator=(AirObjectRetain &foo)
//        {
//            (&foo)->p_t->retain();
//            if (NULL != AirObjectBasePtr<T>::p_t) {
//                AirObjectBasePtr<T>::p_t->release();
//            }
//            AirObjectBasePtr<T>::p_t = &(*(&foo)->p_t);
//            return *this;
//        }
//        
//        AirObjectRetain &operator=(const AirObjectRetain &foo)
//        {
//            (&foo)->p_t->retain();
//            if (NULL != AirObjectBasePtr<T>::p_t) {AirObjectBasePtr<T>::p_t->release();
//            }
//            AirObjectBasePtr<T>::p_t = &(*(&foo)->p_t);
//            return *this;
//        }
//        
//        AirObjectRetain &operator=(AirObjectPtr<AirObjectAssign, T> &foo)
//        {
//            (&foo)->p_t->retain();
//            if (NULL != AirObjectBasePtr<T>::p_t) {AirObjectBasePtr<T>::p_t->release();
//            }
//            AirObjectBasePtr<T>::p_t = &(*(&foo)->p_t);
//            return *this;
//        }
//        
//        AirObjectRetain &operator=(const AirObjectPtr<AirObjectAssign, T> &foo)
//        {
//            (&foo)->p_t->retain();
//            if (NULL != AirObjectBasePtr<T>::p_t) {AirObjectBasePtr<T>::p_t->release();
//            }
//            AirObjectBasePtr<T>::p_t = &(*(&foo)->p_t);
//            return *this;
//        }
//        
//        AirObjectRetain &operator=(AirObjectPtr<AirObjectCopy, T> &foo)
//        {
//            (&foo)->p_t->retain();
//            if (NULL != AirObjectBasePtr<T>::p_t) {AirObjectBasePtr<T>::p_t->release();
//            }
//            AirObjectBasePtr<T>::p_t = &(*(&foo)->p_t);
//            return *this;
//        }
//        
//        AirObjectRetain &operator=(const AirObjectPtr<AirObjectCopy, T> &foo)
//        {
//            (&foo)->p_t->retain();
//            if (NULL != AirObjectBasePtr<T>::p_t) {AirObjectBasePtr<T>::p_t->release();
//            }
//            AirObjectBasePtr<T>::p_t = &(*(&foo)->p_t);
//            return *this;
//        }
//    };
//    
//    template <class T>
//    class AirObjectCopy : public AirObjectBasePtr<T>{
//    public:
//        
//        AirObjectCopy(){ AirObjectBasePtr<T>::p_t = NULL;}
//        
//        AirObjectCopy(T *t){
//            AirObjectBasePtr<T>::p_t = t->copy();
//        }
//        
//        AirObjectCopy(AirObjectPtr<AirObjectRetain, T> &foo){ AirObjectBasePtr<T>::p_t = foo.p_t; }
//        AirObjectCopy(AirObjectPtr<AirObjectAssign, T> &foo){ AirObjectBasePtr<T>::p_t = foo.p_t; }
//        
//        ~AirObjectCopy(){
//            if (AirObjectBasePtr<T>::p_t!=NULL) {
//                AirObjectBasePtr<T>::p_t->release();
//            }
//            AirObjectBasePtr<T>::p_t = NULL;
//        }
//        
//        T& operator *(){
//            return *AirObjectBasePtr<T>::p_t;
//        }
//        
//        T* operator ->(void){
//            return AirObjectBasePtr<T>::p_t;
//        }
//        
//        bool operator ==(T& t){
//            return AirObjectBasePtr<T>::p_t == &t;
//        }
//        
//        AirObjectCopy *operator=(T *_t)
//        {
//            if (AirObjectBasePtr<T>::p_t!=NULL) {
//                AirObjectBasePtr<T>::p_t->release();
//            }
//            AirObjectBasePtr<T>::p_t = _t->copy();
//            return this;
//        }
//        
//        AirObjectCopy &operator=(T &_t)
//        {
//            if (AirObjectBasePtr<T>::p_t!=NULL) {
//                AirObjectBasePtr<T>::p_t->release();
//            }
//            AirObjectBasePtr<T>::p_t = _t.copy();
//            return *this;
//        }
//        
//        AirObjectCopy &operator=(AirObjectCopy &foo)
//        {
//            if (AirObjectBasePtr<T>::p_t!=NULL) {
//                AirObjectBasePtr<T>::p_t->release();
//            }
//            AirObjectBasePtr<T>::p_t = &(*(&foo)->p_t->copy());
//            return *this;
//        }
//        
//        AirObjectCopy &operator=(const AirObjectCopy &foo)
//        {
//            if (AirObjectBasePtr<T>::p_t!=NULL) {
//                AirObjectBasePtr<T>::p_t->release();
//            }
//            AirObjectBasePtr<T>::p_t = &(*(&foo)->p_t->copy());
//            return *this;
//        }
//        
//        AirObjectCopy &operator=(AirObjectPtr<AirObjectAssign, T> &foo)
//        {
//            if (AirObjectBasePtr<T>::p_t!=NULL) {
//                AirObjectBasePtr<T>::p_t->release();
//            }
//            AirObjectBasePtr<T>::p_t = &(*(&foo)->p_t->copy());
//            return *this;
//        }
//        
//        AirObjectCopy &operator=(const AirObjectPtr<AirObjectAssign, T> &foo)
//        {
//            if (AirObjectBasePtr<T>::p_t!=NULL) {
//                AirObjectBasePtr<T>::p_t->release();
//            }
//            AirObjectBasePtr<T>::p_t = &(*(&foo)->p_t->copy());
//            return *this;
//        }
//        
//        AirObjectCopy &operator=(AirObjectPtr<AirObjectRetain, T> &foo)
//        {
//            if (AirObjectBasePtr<T>::p_t!=NULL) {
//                AirObjectBasePtr<T>::p_t->release();
//            }
//            AirObjectBasePtr<T>::p_t = &(*(&foo)->p_t->copy());
//            return *this;
//        }
//        
//        AirObjectCopy &operator=(const AirObjectPtr<AirObjectRetain, T> &foo)
//        {
//            if (AirObjectBasePtr<T>::p_t!=NULL) {
//                AirObjectBasePtr<T>::p_t->release();
//            }
//            AirObjectBasePtr<T>::p_t = &(*(&foo)->p_t->copy());
//            return *this;
//        }
//    };
//    
//    template <template <class> class Protocol, class T>
//    class AirObjectPtr : public Protocol<T>{
//    public:
//        AirObjectPtr():Protocol<T>(){ }
//        
//        AirObjectPtr(T *t):Protocol<T>(t){ }
//        
////        AirObjectPtr(AirObjectPtr<AirObjectRetain, T> &foo):Protocol<T>(foo){ }
////        
////        AirObjectPtr(AirObjectPtr<AirObjectCopy, T> &foo):Protocol<T>(foo){ }
////        
////        AirObjectPtr(AirObjectPtr<AirObjectAssign, T> &foo):Protocol<T>(foo){ }
//        
//        using Protocol<T>::operator=;
//    };
//}
//#endif /* defined(__AirMem__AirObjectRefPoint__) */
